//
//  ProfileController.swift
//  用户资料界面
//
//  Created by smile on 2019/7/16.
//  Copyright © 2019 ixuea. All rights reserved.
//

import UIKit

//导入TextView提示框架
import KMPlaceholderTextView

//导入发布订阅框架
import SwiftEventBus

class ProfileController: BaseTitleController {
    
    
    /// 头像容器
    @IBOutlet weak var svAvatar: UIStackView!
    
    /// 头像
    @IBOutlet weak var ivAvatar: UIImageView!
    
    /// 昵称
    @IBOutlet weak var tfNickname: UITextField!
    
    /// 性别容器
    @IBOutlet weak var svGender: UIStackView!
    
    /// 性别
    @IBOutlet weak var lbGender: UILabel!
    
    /// 生日容器
    @IBOutlet weak var svBrithday: UIStackView!
    
    /// 生日
    @IBOutlet weak var lbBrithday: UILabel!
    
    /// 地区容器
    @IBOutlet weak var svArea: UIStackView!
    
    /// 地区
    @IBOutlet weak var lbArea: UILabel!
    
    /// 描述
    @IBOutlet weak var tvDescription: KMPlaceholderTextView!
    
    /// 手机号
    @IBOutlet weak var lbPhone: UILabel!
    
    /// 邮箱
    @IBOutlet weak var lbEmail: UILabel!
    
    /// QQ按钮
    @IBOutlet weak var btQQ: UIButton!
    
    /// 微博按钮
    @IBOutlet weak var btWeibo: UIButton!
    
    /// 用户对象
    var data:User!
    
    /// 用户头像
    var avatarFilename:String?
    
    /// 省
    var province:AddressModel?
    
    /// 市
    var city:AddressModel?
    
    /// 区
    var area:AddressModel?
    
    /// 生日
    var birthday:String?
    
    /// 性别
    var gender:Int?
    
    override func initViews() {
        super.initViews()
        
        setTitle("我的资料")
        
        //圆角
        ViewUtil.showRadius(ivAvatar, 30)
        
        ViewUtil.showRadius(btQQ, 15)
        ViewUtil.showRadius(btWeibo, 15)
        
        //创建右侧保存按钮
        let saveBarItem=UIBarButtonItem(title: "保存", style: .plain, target: self, action: #selector(onSaveClick))
        
        //将按钮添加到导航栏右侧
        navigationItem.rightBarButtonItem=saveBarItem
    }
    
    /// 保存按钮点击
    @objc func onSaveClick() {
        print("ProfileController onSaveClick")
        
        //这里就不判断用户是否更改了资料
        //只要点击保存就更新
        
        //获取昵称
        let nickname=tfNickname.text!.trim()!
        
        //判断是否输入了昵称
        if nickname.isEmpty {
            ToastUtil.short("请输入昵称！")
            return
        }
        
        //判断昵称格式
        guard nickname.isNickname() else {
            ToastUtil.short("昵称长度不对！")
            return
        }
        
        updateUserInfo(nickname:nickname,description:tvDescription.text.trim(),gender:gender,birthday:birthday,province:province?.region_name,province_code:province?.region_id,city:city?.region_name,city_code:city?.region_id,area:area?.region_name,area_code:area?.region_id)
    }
    
    override func initDatas() {
        super.initDatas()
        
        fetchData()
    }
    
    func fetchData() {
        Api.shared.userDetail(id: PreferenceUtil.userId()!).subscribeOnSuccess { (data) in
            if let data=data?.data {
                self.showData(data)
            }
        }.disposed(by: disposeBag)
    }
    
    func showData(_ data:User) {
        self.data=data
        
        //显示头像
        ImageUtil.showAvatar(ivAvatar, data.avatar)
        
        //显示昵称
        tfNickname.text=data.nickname
        
        //性别
        lbGender.text=data.formatGender
        
        //生日
        if let birthday = data.birthday {
            lbBrithday.text=birthday
        }
        
        //显示地区
        if let province = data.province {
            showArea(province,data.city!,data.area!)
        }
        
        //描述
        if let description = data.description {
            tvDescription.text=description
        }
        
        //手机号
        lbPhone.text=data.phone
        
        //邮箱
        lbEmail.text=data.email
        
        //QQ绑定状态
        if let _ = data.qq_id {
            //已经绑定了
            
            //显示解绑状态
            showUnbindButtonStatus(btQQ)
        }else{
            //没有绑定
            
            //显示绑定状态
            showBindButtonStatus(btQQ)
        }
        
        //微博绑定状态
        if let _ = data.weibo_id {
            //已经绑定了
            
            //显示解绑状态
            showUnbindButtonStatus(btWeibo)
        }else{
            //没有绑定
            
            //显示绑定状态
            showBindButtonStatus(btWeibo)
        }
        
        
    }
    
    /// 显示绑定按钮状态
    ///
    /// - Parameter button: <#button description#>
    func showBindButtonStatus(_ button:UIButton) {
        button.setTitle("绑定", for: .normal)
        button.setTitleColor(UIColor(hex: COLOR_PRIMARY), for: .normal)
        button.showColorPrimaryBorder()
    }
    
    /// 显示解绑按钮状态
    ///
    /// - Parameter button: <#button description#>
    func showUnbindButtonStatus(_ button:UIButton) {
        button.setTitle("解绑", for: .normal)
        button.setTitleColor(UIColor.lightGray  , for: .normal)
        button.showBorder(UIColor.lightGray)
    }
    
    
    /// 显示地区
    ///
    /// - Parameters:
    ///   - province: <#province description#>
    ///   - city: <#city description#>
    ///   - area: <#area description#>
    func showArea(_ province:String,_ city:String,_ area:String)  {
        lbArea.text="\(province)-\(city)-\(area)"
    }
    
    override func initListeners() {
        super.initListeners()
        
        //头像容器点击
        svAvatar.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(onAvatarClick)))
        
        //性别容器点击
        svGender.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(onGenderClick)))
        
        //生日容器点击
        svBrithday.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(onBrithdayClick)))
        
        //地区容器点击
        svArea.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(onAreaClick)))
    }
    
    /// 头像容器点击
    @objc func onAvatarClick() {
        print("ProfileController onAvatarClick")
        
        //创建选择图片控制器
        let picker=UIImagePickerController()
        
        //设置代理
        picker.delegate=self
        
        //选择源
        //photoLibrary：是相册库
        //还可以从摄像头选择
        picker.sourceType = .photoLibrary
        
        //允许编辑
        //选择完图片后
        //有一个裁剪框
        //但没法指定裁剪尺寸
        //或者比例
        
        //但可以手势缩放被裁剪的图片
        //在这里对我们来说够用了
        
        //头像不是说图片越小越好
        //因为万一要实现高清头像
        picker.allowsEditing = true
        
        //显示样式
        picker.modalTransitionStyle = .coverVertical
        
        //显示控制器
        present(picker, animated: true, completion: nil)
    }
    
    /// 性别容器点击
    @objc func onGenderClick() {
        print("ProfileController onGenderClick")

        BHJPickerView(self, .gender).pickerViewShow()
    }
    
    /// 生日容器点击
    @objc func onBrithdayClick() {
        print("ProfileController onBrithdayClick")
        
        //真实项目中会控制生日
        //不能选择当前以后的日志
        //这里就不实现了
        BHJPickerView(self, .date).pickerViewShow()
    }
    
    /// 地区容器点击
    @objc func onAreaClick() {
        print("ProfileController onAreaClick")
        
        //真实项目中
        //可以会实现弹出后
        //显示用户以前的位置
        //或者使用定位
        BHJPickerView(self,.address).pickerViewShow()
    }
    
    /// QQ按钮点击
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onQQClick(_ sender: Any) {
        print("ProfileController onQQClick")
        
        if let _ = data.qq_id {
            //已经绑定了
            
            //弹出解绑对话框
            //因为我们本质是想留住用户
            //防止用户误操作
            showUnbindDialog(PLATFORM_QQ)
        } else {
            //没有绑定
            
            //调用绑定方法
            otherLogin(.typeQQ)
        }
        
    }
    
    /// 显示解绑对话框
    ///
    /// - Parameter platform: <#platform description#>
    func showUnbindDialog(_ platform:Int) {
        //框架控制器
        let controller=UIAlertController(title: "提示", message: "你确定解绑吗？", preferredStyle: .alert)
        
        //确定回调
        let confirmAction=UIAlertAction(title: "确定", style: .default) { (action) in
            self.unbindAccount(platform)
        }
        
        //取消回调
        let cancelAction=UIAlertAction(title: "取消", style: .default, handler: nil)
        
        //动作添加到控制器
        controller.addAction(confirmAction)
        controller.addAction(cancelAction)
        
        //显示弹窗
        present(controller, animated: true, completion: nil)
    }
    
    /// 解绑
    ///
    /// - Parameter platform: <#platform description#>
    func unbindAccount(_ platform:Int) {
        Api.shared.unbindAccount(platform).subscribeOnSuccess { (data) in
            ToastUtil.short("解绑成功！")
            
            self.fetchData()
        }.disposed(by: disposeBag)
    }
    
    /// 微博按钮点击
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onWeiboClick(_ sender: Any) {
        print("ProfileController onWeiboClick")
        
        if let _ = data.weibo_id {
            //已经绑定了
            
            //弹出解绑对话框
            //因为我们本质是想留住用户
            //防止用户误操作
            showUnbindDialog(PLATFORM_WEIBO)
        } else {
            //没有绑定
            
            //调用绑定方法
            otherLogin(.typeSinaWeibo)
        }
        
    }
    
    /// 第三方登录
    ///
    /// - Parameter type: <#type description#>
    func otherLogin(_ type:SSDKPlatformType) {
        ShareSDK.getUserInfo(type) { (state, user, error) in
            if state == .success {
                //登录成功
                
                //获取到OpenId
                let openId=user!.credential.token!
//                let openId="234rljdgfdgfgg"
                
                //调用继续登录的方法
                self.continueLogin(type,openId)
            }else if state == .cancel {
                //取消
                
            }else{
                //登录失败了
                let nsError = error as! NSError
                print("ProfileController login failed:\(nsError)")
                ToastUtil.short("绑定失败，请稍后再试！")
            }
        }
    }
    
    /// 继续登录
    ///
    /// - Parameters:
    ///   - type: <#type description#>
    ///   - openId: <#openId description#>
    func continueLogin(_ type:SSDKPlatformType,_ openId:String) {
        
        /// 判断平台
        var platform:Int!
        
        if type == .typeQQ {
            //QQ
            platform=PLATFORM_QQ
        } else {
            //微博
            platform=PLATFORM_WEIBO
        }
        
        //调用接口将第三方用户的信息
        //绑定到当前登录的用户
        Api.shared.bindAccount(openId, platform).subscribeOnSuccess { (data) in
            ToastUtil.short("绑定成功！")
            
            self.fetchData()
        }.disposed(by: disposeBag)
    }
    
    /// 上传头像
    ///
    /// - Parameter data: <#data description#>
    func uploadAvatar(_ data:UIImage) {
        //由于头像一般比较小
        //同时也只有一张图片
        //所以可以不用显示加载框
        let oss=IxueaOSSUtil.shared()
        
        //在异步任务中上传图片
        DispatchQueue.global().async {
            //这里是子线程
            
            let putObjectRequest=OSSPutObjectRequest()
            putObjectRequest.bucketName=ALIYUN_OSS_BUCKET_NAME
            
            //上传
            //如果没有特殊需求建议不要分目录
            //因为当请求达到一定量级会有性能影响
            //如果一定要分目录
            //不要让目录名前面连续
            //例如时间戳倒过来
            self.avatarFilename="\(UUIDUtil.uuid()).jpg"
            putObjectRequest.objectKey=self.avatarFilename!
            
            //将图片转为data数据
            //指令为50%
            //值越小质量越差
            //体积越小
            let imageData=data.jpegData(compressionQuality: 0.5)
            
            //直接上传NSData
            putObjectRequest.uploadingData=imageData!
         
            //上传进度
            putObjectRequest.uploadProgress = {
                bytesSent,totalByteSent,totalBytesExpectedToSend in
                //这里没用到
                //所有就打印日志
                //真实项目中可能会显示到图片上
                print("ProfileController upload image:\(bytesSent),\(totalByteSent),\(totalBytesExpectedToSend)")
            }
            
            //上传
            let putTask=oss.putObject(putObjectRequest)
            
            //上传完回调
            putTask.continue({ (task) -> Any? in
                if task.error == nil {
                    //上传成功
                    print("ProfileController upload image success:\(self.avatarFilename!)")
                }else{
                    //上传失败
                    print("ProfileController upload image failed:\(task.error)")
                    self.avatarFilename=nil
                }
                
                return nil
            })
            
            //同步等待
            putTask.waitUntilFinished()
            
        }
        
        
        //图片上传完毕
        DispatchQueue.main.async {
            //这里是主线程
            
            if let avatarFilename=self.avatarFilename{
                //头像上传成功
                print("ProfileController upload avatar succes:\(avatarFilename)")
                
                //更新用户资料
                self.updateUserInfo(avatar:self.avatarFilename)
            }else{
                //头像上传失败
                print("ProfileController upload avatar failed:\(self.avatarFilename)")
                ToastUtil.short("上传头像失败，请稍后再试!")
            }
        }
    }
    
    /// 更新用户资料
    ///
    /// - Parameters:
    ///   - nickname: 昵称
    ///   - avatar: 头像
    ///   - description: 描述
    ///   - gender: 性别
    ///   - birthday: 生日
    ///   - province: 省
    ///   - province_code: 省代码
    ///   - city: 市
    ///   - city_code: 市代码
    ///   - area: 区
    ///   - area_code: 区代码
    func updateUserInfo(nickname:String?=nil,avatar:String?=nil,description:String?=nil,gender:Int?=nil,birthday:String?=nil,province:String?=nil,province_code:String?=nil,city:String?=nil,city_code:String?=nil,area:String?=nil,area_code:String?=nil) {
        Api.shared.updateUser(id: PreferenceUtil.userId()!, nickname: nickname, avatar: avatar, description: description, gender: gender, birthday: birthday, province: province, province_code: province_code, city: city, city_code: city_code, area: area, area_code: area_code).subscribeOnSuccess { (data) in
            //更新成功
            //不提示任何信息
            
            //关闭当前界面
            //当然也可以不关闭
            //真实项目中根据业务需求调整就行了
            
            //发送通知
            SwiftEventBus.post(ON_USER_INFO_CHANGED)
            
            //关闭当前界面
            self.navigationController?.popViewController(animated: true)
        }.disposed(by: disposeBag)
    }
}

// MARK: - 启动方法
extension ProfileController{
    
    /// 启动方法
    ///
    /// - Parameter nav: <#nav description#>
    static func start(_ nav:UINavigationController) {
        //获取控制器
        let controller=nav.storyboard!.instantiateViewController(withIdentifier: "Profile")
        
        //放入导航控制器
        nav.pushViewController(controller, animated: true)
    }
}

// MARK: - 实现选择图片代理
extension ProfileController:UINavigationControllerDelegate,UIImagePickerControllerDelegate{
    
    /// 取消选择图片
    ///
    /// - Parameter picker: <#picker description#>
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        //关闭选择图片控制器
        picker.dismiss(animated: true, completion: nil)
    }
    
    /// 选择了图片
    ///
    /// - Parameters:
    ///   - picker: <#picker description#>
    ///   - info: <#info description#>
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        
        picker.dismiss(animated: true, completion: nil)
        
        //获取编辑的后图片
        //如果没有编辑
        //需要通过其他字段获取
        if let image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage {
            //选择了图片
            print("ProfileController didFinishPickingMediaWithInfo select image succes")
            
            //上传图片
            uploadAvatar(image)
        }
    }
}

// MARK: - 选择器代理
extension ProfileController:PickerDelegate{
    
    /// 选择了地址
    ///
    /// - Parameters:
    ///   - pickerView: <#pickerView description#>
    ///   - procince: <#procince description#>
    ///   - city: <#city description#>
    ///   - area: <#area description#>
    func selectedAddress(_ pickerView: BHJPickerView, _ procince: AddressModel, _ city: AddressModel, _ area: AddressModel) {
        print("ProfileController selectedAddress:\(procince),\(city),\(area)")
        
        //保存到当前类中
        //点击保存的时候从这些字段上获取数据
        self.province=procince
        self.city=city
        self.area=area
        
        //显示地址
        showArea(procince.region_name!, city.region_name!, area.region_name!)
    }
    
    /// 选择了日期
    ///
    /// - Parameters:
    ///   - pickerView: <#pickerView description#>
    ///   - dateStr: <#dateStr description#>
    func selectedDate(_ pickerView: BHJPickerView, _ dateStr: Date) {
        print("ProfileController selectedDate:\(dateStr)")
        
        self.birthday=TimeUtil.date2yyyyMMdd(dateStr)
        
        lbBrithday.text=birthday!
    }
    
    /// 选择了性别
    ///
    /// - Parameters:
    ///   - pickerView: <#pickerView description#>
    ///   - genderStr: <#genderStr description#>
    func selectedGender(_ pickerView: BHJPickerView, _ genderStr: String) {
        print("ProfileController selectedGender:\(genderStr)")
        
        //真实项目要写到常量类中
        if "男" == genderStr {
            self.gender=10
        } else {
            //女
            self.gender=20
        }
        
        lbGender.text=genderStr
    }
    
    
}
